#! /bin/sh
# check_routes:	Script to detect if we are having issues using an upstream
#		connection, it can use the variables from netsane and it
#		will also use netsane to make the appropiat failover
#		This code comes in part after the backroute script from
#		Bernhard Brunner
#
# Licensed under the GPL License

# WHERE IS THE CONF?
WHERE_IS_NETSANE_CONF_LOCATED="/etc/netsane/netsane.conf"

# WHERE IS THE BINARY?
NETSANE_BIN="/root/scripts/netsane.sh"

## Begin
if [ ! -e "$WHERE_IS_NETSANE_CONF_LOCATED" ] ; then
        echo "[check_routes] Missing netsane config file!"
        exit 1
else
        . $WHERE_IS_NETSANE_CONF_LOCATED
fi

if [ ! -e "$NETSANE_BIN" ] ; then
        echo "[check_routes] Missing netsane binary file!"
        exit 1
fi

#statefile. this contains variables related to state
statefile=/var/run/check_routes.stat

#IP for gateway 1
UPSTREAMGW1=$IP1_GW
#IP for gateway 2
UPSTREAMGW2=$IP2_GW
#IP for a gateway 1 only host
UPSTREAMH1=$IP1_ALWAYS
#IP for a gateway 2 only host
UPSTREAMH2=$IP2_ALWAYS

#TODO, detect empty values

# logfile where up/down events are logged. 
fastlog=/var/log/fastfail

##END OF CONFIGURATION#############################################

# sane defaults for statefile variables:
# FASTDOWN1=0|1
dirty=0
FASTDOWN1=0
FASTDOWN2=0
mailto=root

if [ -e $statefile ] ; then
    . $statefile
else
    #No state file created
    dirty=1
fi

#Check the upstream connectivity by pinging an upstream router and a host to see if we
# have proper connectivity
#TODO, some logic could be added to check those ips without having
# to permanently put them on a interface, meanwhile we will use IP1_ALWAYS/IP2_ALWAYS
ping -q -w 5 -c3 $UPSTREAMGW1 > /dev/null
PINGGW1=$?
ping -q -w 5 -c3 $UPSTREAMGW2 > /dev/null
PINGGW2=$?
ping -q -w 5 -c3 $UPSTREAMH1 > /dev/null
PINGH1=$?
ping -q -w 5 -c3 $UPSTREAMH2 > /dev/null
PINGH2=$?

#Mark gateways as failed when needed
if [ "$PINGGW1" != "0" -o "$PINGH1" != "0" ] && [ "$FASTDOWN1" = "0" ] ; then
	echo "[check_routes] Gateway $IF1_NAME ($IP1_GW) is not answering, dropping that route!"
	sh $NETSANE_BIN -dip1
	echo "Down $IF1_NAME `date +'down %D %T'`" >> $fastlog
	logger -t netsane "Down $IF1_NAME"
	if [ ! -z "$ADMIN_MAIL" ] ; then
		echo "Down $IF1_NAME" | mail -s "Netsane alert" $ADMIN_MAIL
	fi
	FASTDOWN1=1
	dirty=1
elif [ "$PINGGW2" != "0" -o "$PINGH2" != "0" ] && [ "$FASTDOWN2" = "0" ] ; then
        echo "[check_routes] Gateway $IF2_NAME ($IP2_GW) is not answering, dropping that route!"
        sh $NETSANE_BIN -dip2
	echo "Down $IF2_NAME `date +'down %D %T'`" >> $fastlog
	logger -t netsane "Down $IF2_NAME"
	if [ ! -z "$ADMIN_MAIL" ] ; then
		echo "Down $IF2_NAME" | mail -s "Netsane alert" $ADMIN_MAIL
	fi
	FASTDOWN2=1
	dirty=1
fi

#Mark gateways as recovered when detected
#TODO, check if there are services that need to be reloaded on changes
if [ "$PINGGW1" = "0" -a "$PINGH1" = "0" ] && [ "$FASTDOWN1" = "1" ] ; then
	echo "[check_routes] Gateway $IF1_NAME ($IP1_GW) is back, setting the defaults!"
        sh $NETSANE_BIN restart
        echo "Recovered $IF1_NAME `date +'up %D %T'`" >> $fastlog
        logger -t netsane "Recovered $IF1_NAME"
	if [ ! -z "$ADMIN_MAIL" ] ; then
		echo "Recovered $IF1_NAME" | mail -s "Netsane alert" $ADMIN_MAIL
	fi
	FASTDOWN1=0
	dirty=1
elif [ "$PINGGW2" = "0" -a "$PINGH2" = "0" ] && [ "$FASTDOWN2" = "1" ] ; then
	echo "[check_routes] Gateway $IF2_NAME ($IP2_GW) is back, setting the defaults!"
        sh $NETSANE_BIN restart
        echo "Recovered $IF2_NAME `date +'up %D %T'`" >> $fastlog
        logger -t netsane "Recovered $IF2_NAME"
	if [ ! -z "$ADMIN_MAIL" ] ; then
		echo "Recovered $IF2_NAME" | mail -s "Netsane alert" $ADMIN_MAIL
	fi
	FASTDOWN2=0
	dirty=1
fi 

#Recreate the statefile
if [ "$dirty" = "1" ] ; then
  echo FASTDOWN1=$FASTDOWN1 > $statefile
  echo FASTDOWN2=$FASTDOWN2 >> $statefile
fi

